package com.corpgovernment.travelstandard.controller;

import com.corpgovernment.api.organization.model.post.PostVo;
import com.corpgovernment.api.travelstandard.bo.HotelTravelForAppRequestBO;
import com.corpgovernment.api.travelstandard.enums.*;
import com.corpgovernment.api.travelstandard.service.IAreaConfigService;
import com.corpgovernment.api.travelstandard.utils.MyMap;
import com.corpgovernment.api.travelstandard.vo.*;
import com.corpgovernment.api.travelstandard.vo.request.AppShowHotelTravelStandardRequest;
import com.corpgovernment.api.travelstandard.vo.request.ExecuteHotelTravelStandardRequest;
import com.corpgovernment.api.travelstandard.vo.request.GetHotelDetailListRequest;
import com.corpgovernment.api.travelstandard.vo.request.GetHotelDetailRequest;
import com.corpgovernment.api.travelstandard.vo.response.AppShowHotelTravelStandardResponse;
import com.corpgovernment.api.travelstandard.vo.response.ExecuteHotelTravelStandardSoaResponse;
import com.corpgovernment.common.base.BaseUserInfo;
import com.corpgovernment.common.base.JSONResult;
import com.corpgovernment.common.common.CorpBusinessException;
import com.corpgovernment.common.currency.CurrencyConversionUtil;
import com.corpgovernment.common.currency.bo.CurrencyBO;
import com.corpgovernment.travelstandard.vo.*;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.StringUtils;
import com.corpgovernment.organization.constant.OrganizationResponseCodeEnum;
import com.corpgovernment.travelstandard.vo.HotelQuarterDownloadRequestVo;
import com.corpgovernment.travelstandard.vo.HotelQuarterUploadDetailPageRequestVo;
import com.corpgovernment.travelstandard.vo.HotelQuarterUploadPageRequestVo;
import com.corpgovernment.organization.service.IPostService;
import com.corpgovernment.travelstandard.impl.*;
import com.corpgovernment.travelstandard.utils.BeanConverUtil;
import com.corpgovernment.travelstandard.vo.GetHotelTravelStandardResponseVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@Slf4j
@RestController
@RequestMapping("hotelTravelStandardManage")
public class HotelTravelStandardManageController {

    private final static String HOTEL_TRAVEL_STANDARD_DEFAULT_NAME = "酒店差旅标准";

    @Autowired
    private TravelStandardPostService standPostService;
	@Autowired
	private IPostService postService;
    @Autowired
    private MbTravelstandHotelService travelstandHotelService;
    @Autowired
    private MbTravelstandReasonCodeService travelstandReasonCodeService;
    @Autowired
    private MbTravelstandHotelPriceService travelstandHotelPriceService;
    @Autowired
    private IAreaConfigService areaConfigService;
    @Autowired
    private CityConfigService cityConfigService;
    @Autowired
    private MbTravelstandHotelQuarterService travelstandHotelQuarterService;

    /**
     * 新增酒店差标
     *
     * @return
     */
    @RequestMapping("toAdd")
    public JSONResult toAddHotelTravelStandrad(@RequestBody HotelTravelStandardManageVo travelStandardManageVo) {
        String title = travelStandardManageVo.getTitle();
        if (StringUtils.isBlank(title)) {
            title = HOTEL_TRAVEL_STANDARD_DEFAULT_NAME;
        }
        String orgId = travelStandardManageVo.getOrgId();
        if (StringUtils.isBlank(orgId)) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.ORG_ID_NULL);
        }
        MbTravelstandHotelVo travelstandHotelVo = new MbTravelstandHotelVo(
                null,
                orgId,
                title,
                HotelSwitchEnum.priceSwitch.N.getCode(),
                ControlTypeEnum.F.getCode(),
                HotelSwitchEnum.QuarterSwitch.N.getCode(),
                HotelSwitchEnum.priceSwitch.N.getCode(),
                HotelSwitchEnum.SharedSwitch.N.getCode(),
                HotelManageRulesEnum.LOW.getCode(),
                null,
                HotelSwitchEnum.SharedSwitch.N.getCode(),
                HotelSwitchEnum.SharedSwitch.N.getCode(),
                HotelSwitchEnum.SharedSwitch.N.getCode(),
                ControlTypeEnum.A.getCode(),
                HotelManageStrategyEnum.ORDER.getCode()

        );
        travelstandHotelVo.setHotelProductSwitch("E");
        travelstandHotelVo.setHotelIntlProductSwitch("E");
        travelstandHotelService.insertTravelstandHotel(travelstandHotelVo);
        //获取RC列表
        List<MbTravelstandReasonCodeVo> travelstandReasonCodeVos = travelstandReasonCodeService.list(new MbTravelstandReasonCodeVo(){{setTsId(travelstandHotelVo.getId());setTsType(TravelStandardTypeEnum.Hotel.getCode());}});
        //获取价格列表
        List<MbTravelstandHotelPriceVo> travelstandHotelPriceVos = travelstandHotelPriceService.listAllTravelstandHotelPrice(travelstandHotelVo.getId(),travelstandHotelVo.getOrgId());
        //获取淡旺季信息
        List<MbTravelstandHotelQuarterVo> travelstandHotelQuarterVos = travelstandHotelQuarterService.list(
                new MbTravelstandHotelQuarterVo().setTsHotelId(travelstandHotelVo.getId())
        );
        Map<String,Object> returnMap = new HashMap<>();
        returnMap.put("hotelControl", BeanConverUtil.travelstandHotelVoToHotelTravelStandardManageVo(
                travelstandHotelVo,
                new ArrayList<>(),
                travelstandReasonCodeVos,
                travelstandHotelPriceVos,
                travelstandHotelQuarterVos
        ));
        return JSONResult.success(returnMap);
    }

    /**
     *  更新酒店差标属性
     * @param vo
     * @return
     */

    @RequestMapping("save")
    public JSONResult saveHotelTravelStandard(@RequestBody HotelTravelStandardManageVo vo) {
        return travelstandHotelService.updateTravelstandHotelProperty(vo);
    }


    /**
     * 酒店差标名称更新
     */
    @RequestMapping("updateStandardName")
    public JSONResult updateStandardName(@RequestBody HotelTravelStandardManageVo travelStandardManageVo) {
        String id = travelStandardManageVo.getId();
        if (StringUtils.isBlank(id)){
            throw new CorpBusinessException(OrganizationResponseCodeEnum.PARAMS_IS_NULL, "id");
        }
        String title = travelStandardManageVo.getTitle();
        if (StringUtils.isBlank(title)){
            throw new CorpBusinessException(OrganizationResponseCodeEnum.PARAMS_IS_NULL, "title");
        }
        travelstandHotelService.updateStandardName(Long.valueOf(id),title);
        return JSONResult.ok();
    }

    /**
     * 删除酒店差标
     * @param travelStandardManageVo
     * @return
     */
    @RequestMapping("delete")
    public JSONResult deleteHotelTravelStandard(@RequestBody HotelTravelStandardManageVo travelStandardManageVo) {
        String id = travelStandardManageVo.getId();
        if (StringUtils.isBlank(id)) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.PARAMS_IS_NULL, "id");
        }
        return travelstandHotelService.deleteTravelstandHotel(Long.valueOf(id));
    }

    /**
     * 获取酒店差标
     */
    @RequestMapping("get")
    public JSONResult<GetHotelTravelStandardResponseVo> getHotelTravelStandard(@RequestBody HotelTravelStandardManageVo travelStandardManageVo) {
        String orgId = travelStandardManageVo.getOrgId();
        if (StringUtils.isBlank(orgId)) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.ORG_ID_NULL);
        }
        List<HotelTravelStandardManageVo> domAirTicket = travelstandHotelService.listTravelstandHotel(new MbTravelstandHotelVo(){{setOrgId(orgId);}});
        //全部岗位
        List<PostVo> posts = postService.listPostByOrgId(orgId);
        //已选职位
        List<TravelStandardPostVo> travelStandardPostVos = standPostService.selectByTsTypeAndOrgId(TravelStandardTypeEnum.Hotel.getCode(),orgId);
        List<Long> jobScope = new ArrayList<>();
        for (TravelStandardPostVo travelStandardPostVo : travelStandardPostVos) {
            jobScope.add(travelStandardPostVo.getPostid());
        }

        List<CurrencyBO> currencyBOList = CurrencyConversionUtil.listSupportCurrency();

        GetHotelTravelStandardResponseVo getHotelTravelStandardResponseVo = new GetHotelTravelStandardResponseVo();
        getHotelTravelStandardResponseVo.setHotelControl(domAirTicket);
        getHotelTravelStandardResponseVo.setJobScopeSelectList(jobScope);
        getHotelTravelStandardResponseVo.setJobScopeAllList(posts);

        if(currencyBOList != null) {
            getHotelTravelStandardResponseVo.setCurrencyList(currencyBOList);
        }

        return JSONResult.success(getHotelTravelStandardResponseVo);
    }

    /**
     * 酒店RC更新
     * @return
     */
    @RequestMapping("updateRc")
    public JSONResult updateRc(@RequestBody RCListVo rcListVo) {
        rcListVo.setTsType(TravelStandardTypeEnum.Hotel.getCode());
        travelstandReasonCodeService.updateTravelstandReasonCode(rcListVo);
        return JSONResult.ok();
    }



    /**
     * 下载酒店地区配置模板
     * @param manageVo
     * @param response
     * @return
     */
    @RequestMapping("downloadAreaConfTemplate")
    public JSONResult downloadAreaConfTemplate(@RequestBody HotelTravelStandardManageVo manageVo, HttpServletResponse response) {
        String orgId = manageVo.getOrgId();
        if (StringUtils.isBlank(orgId)) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.HOTEL_TRAVEL_STANDARD_ORG_ID_NULL);
        }
        return travelstandHotelService.downloadAreaConfTemplate(orgId, response);
    }
    /**
     * 上传酒店地区配置表
     * 校验逻辑 see http://idev.ctripcorp.com/share/prod-requirement/10001395/2922232?kanban=45250
     */
    @PostMapping("/syncHotelAreaConfExcel")
    public JSONResult syncHotelAreaConfExcel(HttpServletRequest request, String orgId){
        return travelstandHotelService.syncHotelAreaConfExcel(request, orgId);
    }

    /**
     * 查询酒店地区日志
     *
     * @param requestVo
     * @return
     */
    @PostMapping(value = "/selectAreaConfUploadPage")
    public JSONResult selectAreaConfUploadPage(@RequestBody HotelAreaConfPageRequestVo requestVo) {
        return JSONResult.success(travelstandHotelService.selectAreaConfUploadPage(requestVo));
    }


    /**
     * 查询酒店地区上传错误日志明細
     *
     * @param requestVo
     * @return
     */
    @PostMapping(value = "/selectAreaConfUploadDetailPage")
    public JSONResult selectAreaConfUploadDetailPage(@RequestBody HotelAreaConfDetailPageRequestVo requestVo) {
        return JSONResult.success(travelstandHotelService.selectAreaConfUploadDetailPage(requestVo));
    }


    /**
     * 下载酒店地区配置数据
     */
    @PostMapping(value = "/downloadHotelAreaConf")
    public void downloadHotelAreaConf(@RequestBody HotelCityDownLoadRequestVo requestVo,
                                     HttpServletResponse response) {
        travelstandHotelService.downloadHotelAreaConf(requestVo, response);
    }

    /**
     * 下载酒店地区配置历史上传数据
     */
    @PostMapping(value = "/downloadHotelAreaConfExcel")
    public void downloadHotelAreaConfExcel(@RequestBody HotelCityDownLoadRequestVo requestVo, HttpServletResponse response) {
        travelstandHotelService.downloadHotelAreaConfExcel(requestVo.getUploadId(),requestVo.getFileName(),response);
    }


    @PostMapping("/syncHotelQuarterExcel")
    public JSONResult syncHotelQuarterExcel(@RequestParam("file") MultipartFile file,
                                            MbTravelstandHotelQuarterVo requestVo) {
        return travelstandHotelService.syncHotelQuarterExcel(file, requestVo);
    }

    /**
     * 下载酒店差标淡旺季
     */
    @PostMapping(value = "/downloadHotelQuarter")
    public void downloadHotelQuarter(@RequestBody MbTravelstandHotelQuarterVo requestVo,
                                     HttpServletResponse response) {
        travelstandHotelService.downloadHotelQuarter(requestVo, response);
    }

    /**
     * 下载差标上传文件
     *
     * @param requestVo
     * @param response
     */
    @PostMapping(value = "/downloadQuarterUploadInfoFile")
    public void downloadHotelQuarterUploadInfo(@RequestBody @Validated HotelQuarterDownloadRequestVo requestVo,
                                               HttpServletResponse response) {
        travelstandHotelService.downloadHotelQuarterUploadInfo(requestVo.getId(), response);
    }

    /**
     * 查询差标上传日志
     *
     * @param requestVo
     * @return
     */
    @PostMapping(value = "/selectQuarterUploadInfoPage")
    public JSONResult selectQuarterUploadInfoPage(@RequestBody HotelQuarterUploadPageRequestVo requestVo) {
        return JSONResult.success(travelstandHotelService.selectQuarterUploadInfoPage(requestVo));
    }

    /**
     * 查询差标上传错误日志明细
     *
     * @param requestVo
     * @return
     */
    @PostMapping(value = "/selectQuarterUploadDetailInfoPage")
    public JSONResult selectQuarterUploadDetailInfoPage(@RequestBody HotelQuarterUploadDetailPageRequestVo requestVo) {
        return JSONResult.success(travelstandHotelService.selectQuarterUploadDetailInfoPage(requestVo));
    }

    /**
     * 下载酒店淡旺季模板
     *
     * @param manageVo
     * @param response
     * @return
     */
    @RequestMapping("downloadQuarterTemplate")
    public JSONResult downloadQuarterTemplate(@RequestBody HotelTravelStandardManageVo manageVo,
                                              HttpServletResponse response) {
        String orgId = manageVo.getOrgId();
        if (StringUtils.isBlank(orgId)) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.HOTEL_TRAVEL_STANDARD_ORG_ID_NULL);
        }
        return travelstandHotelService.downloadQuarterTemplate(orgId, response);
    }

    /**
     * SOA-酒店差标展示1
     */
    @RequestMapping("hotlTravelStandardShowSoa")
    public JSONResult<HotelTravelStandardShowVo> hotlTravelStandardShowSoa(@RequestBody TravelStandardSoaRequestVo travelStandardSoaRequestVo){
        return JSONResult.success(travelstandHotelService.hotelTravelStandardShowSoa(travelStandardSoaRequestVo.getUserId(),travelStandardSoaRequestVo.getOrgId()));
    }

    /**
     * APP-展示酒店差标
     */
    @RequestMapping("appShowHotelTravelStandard")
    public JSONResult<AppShowHotelTravelStandardResponse> appShowHotelTravelStandard(@RequestBody AppShowHotelTravelStandardRequest appShowhotelTravelStandardRequest, BaseUserInfo baseUserInfo){
        AppShowHotelTravelStandardResponse appShowhotelTravelStandardResponse = new AppShowHotelTravelStandardResponse();
        MbTravelstandHotelVo mbTravelstandHotelVo = travelstandHotelService.getMbTravelstandHotelVoByuidAndOrgId(baseUserInfo.getUid(),baseUserInfo.getOrgId(), null);
        if (mbTravelstandHotelVo == null){
            return JSONResult.success(appShowhotelTravelStandardResponse);
        }
        List<AreaConfigVo> areaConfigVos;
        if (StringUtils.isNotBlank(appShowhotelTravelStandardRequest.getCityCode())){
            areaConfigVos = areaConfigService.getByOrgIdAndTsIdAndCityCode(
                    baseUserInfo.getCorpId(),
                    appShowhotelTravelStandardRequest.getCityCode(),
                    mbTravelstandHotelVo.getId()
            );
        }
        else {
            areaConfigVos =   areaConfigService.list(
                    new AreaConfigVo(){{
                        setOrgId(baseUserInfo.getCorpId());
                        setStatus(NumberUtils.INTEGER_ZERO);
                    }}
            );
        }
        //将其它地区排在最后一位
        for (AreaConfigVo areaConfigVo : areaConfigVos){
            if (AreaTypeEnum.TYPE_1.getCode().equals(areaConfigVo.getAreaType())){
                areaConfigVos.remove(areaConfigVo);
                areaConfigVos.add(areaConfigVo);
                break;
            }
        }
        List<AppShowHotelTravelStandardResponse.PolicyRuleVo> policyRuleVos = new ArrayList<>();
        for (AreaConfigVo areaConfigVo : areaConfigVos){
            MbTravelstandHotelPriceVo mbTravelstandHotelPriceVo = travelstandHotelPriceService.list(new MbTravelstandHotelPriceVo(){{
                setTsHotelId(mbTravelstandHotelVo.getId());
                setTsHotelAreaId(areaConfigVo.getId());
            }}).get(0);
            AppShowHotelTravelStandardResponse.PolicyRuleVo policyRuleVo = new AppShowHotelTravelStandardResponse.PolicyRuleVo();
            //设置区域名称
            policyRuleVo.setTitle(areaConfigVo.getAreaName());
            //设置地区属性
            List<AppShowHotelTravelStandardResponse.PolicyRuleVo.PolicyDetail> policyDetails = new ArrayList<>();
            AppShowHotelTravelStandardResponse.PolicyRuleVo.PolicyDetail policyDetail1 = new AppShowHotelTravelStandardResponse.PolicyRuleVo.PolicyDetail();
            policyDetail1.setTitle("可订价格");
            BigDecimal priceUpperLimit = mbTravelstandHotelPriceVo.getPriceUpperLimit();
            policyDetail1.setContent(priceUpperLimit == null ? "不限" : "<="+priceUpperLimit.setScale(0, RoundingMode.HALF_UP).toString()+"元/间夜");
            policyDetails.add(policyDetail1);
            policyRuleVo.setPolicyDetail(policyDetails);
            //设置地区城市信息
            MyMap<String, CityVo> cityMap = cityConfigService.getCityInfoList(new AreaConfigVo(){{
                setOrgId(baseUserInfo.getCorpId());
                setId(areaConfigVo.getId());
                setHotelType(areaConfigVo.getHotelType());
            }});
            List<AppShowHotelTravelStandardResponse.PolicyRuleVo.CityInfo> cityInfos = new ArrayList<>();
            if (cityMap != null && areaConfigVo.getAreaType().equals( AreaTypeEnum.TYPE_0.getCode())){
                TreeMap<String,ArrayList<CityVo>> data = cityMap.getData();
                for (String key: data.keySet()){
                    AppShowHotelTravelStandardResponse.PolicyRuleVo.CityInfo cityInfo = new AppShowHotelTravelStandardResponse.PolicyRuleVo.CityInfo();
                    cityInfo.setFirstName(key);
                    String[] citys = new String[data.get(key).size()];
                    int i = 0;
                    for (CityVo cityVo : data.get(key)){
                        citys[i] = cityVo.getCityName();
                        i++;
                    }
                    cityInfo.setCitys(citys);
                    cityInfos.add(cityInfo);
                }
            }
            policyRuleVo.setCityInfos(cityInfos);
            //设置查看城市开关
            if (cityInfos.size()>0){
                policyRuleVo.setType("1");
            }
            else {
                policyRuleVo.setType("0");
            }
            policyRuleVos.add(policyRuleVo);
        }
        appShowhotelTravelStandardResponse.setPolicyRule(policyRuleVos);
        return JSONResult.success(appShowhotelTravelStandardResponse);
    }

	/**
	 * S0A、APP-酒店差标管控
	 *
	 * @param request
	 * @return
	 */
	@RequestMapping("getHotelTravelForApp")
	public JSONResult<List<HotelForAppVo>> getHotelTravelForApp(@RequestBody HotelTravelForAppRequestBO request) {
		return JSONResult.success(travelstandHotelService.getHotelTravelForApp(request.getUid(), request.getOrgId(), request.getCityCode(), request.getPostId(), request.getTrafficId(), request.getProductType(), request.getCheckInTime(), request.getCheckOutTime()));
	}


    /**
     * 给酒店提供
     * @return
     */
    @RequestMapping("getHotelDetail")
    public JSONResult<HotelControlVo> getHotelDetail(@RequestBody GetHotelDetailRequest request){
        return JSONResult.success(travelstandHotelService.getHotelDetail(request));
    }

    /**
     * 给酒店提供
     * @return
     */
    @RequestMapping("getHotelDetailList")
    public JSONResult<Map<String, HotelControlVo>> getHotelDetailList(@RequestBody GetHotelDetailListRequest request){
        return JSONResult.success(travelstandHotelService.getHotelDetailList(request.getHotelDetailRequestList()));
    }


    /**
     * 获取rc内容
     * @param uid
     * @return
     */
    @RequestMapping("getHotelRcInfo")
    public JSONResult<List<ReasonInfo>> getHotelRcInfo(@RequestParam(value = "uid") String uid,@RequestParam(value = "cityCode") String cityCode,@RequestParam(value = "orgId") String orgId){
        return JSONResult.success(travelstandHotelService.getHotelRcInfo(uid, orgId, cityCode));
    }

    /**
     * 执行酒店差标
     * @return
     */
    @PostMapping("/executeHotelTravelStandardSoa")
    public JSONResult<ExecuteHotelTravelStandardSoaResponse> executeHotelTravelStandardSoa(@RequestBody ExecuteHotelTravelStandardRequest request){
        return JSONResult.success(travelstandHotelService.executeHotelTravelStandardSoa(request));
    }

    /**
     * 获得酒店差标
     * @param uid
     * @param orgId
     * @return
     */
    @RequestMapping("getHotelTravelStandard")
    public JSONResult<HotelTravelStandardManageVo> getHotelTravelStandard(@RequestParam(value = "uid") String uid, @RequestParam(value = "orgId") String orgId){
        return new JSONResult<>(travelstandHotelService.getHotelTravelStandard(uid, orgId));
    }

    @RequestMapping("/getHotelSwitch")
    public JSONResult<MbTravelstandHotelVo> getHotelSwitch (@RequestParam(value = "uid") String uid, @RequestParam(value = "orgId") String orgId) {
        return JSONResult.success(travelstandHotelService.getHotelSwitch(uid, orgId));
    }
}
